#pragma once
#ifndef VECTOR_H
#define VECTOR_H

#include <SFML/System.hpp>

#include "Pack.h"

//Inspiriert von Davids Vektorklasse :-)

namespace Private
{
	template<typename T> struct VecHelper
	{
		static inline T sqrt(T X)
		{
			return ::sqrt(X);
		}
	};
	template<> struct VecHelper<short>
	{
		static inline short sqrt(short X)
		{
			return static_cast<short>(::sqrt(static_cast<double>(X)));
		}
	};
	template<> struct VecHelper<int>
	{
		static inline int sqrt(int X)
		{
			return static_cast<int>(::sqrt(static_cast<double>(X)));
		}
	};
	template<> struct VecHelper<long>
	{
		static inline long sqrt(long X)
		{
			return static_cast<long>(::sqrt(static_cast<double>(X)));
		}
	};
	template<> struct VecHelper<long long>
	{
		static inline long long sqrt(long long X)
		{
			return static_cast<long long>(::sqrt(static_cast<double>(X)));
		}
	};




	template<unsigned int Dim, typename T> struct VecBase
	{
	public:
		PACK T Values[Dim];
	};
	
	template<typename T>
	struct VecBase<0, T> {};
	template<typename T>
	struct VecBase<1, T>
	{
	public:
		PACK union
		{
			PACK T Values[1];
			PACK T X;
			PACK T Sfml;
		};
	};
	template<typename T>
	struct VecBase<2, T>
	{
	public:
		PACK union
		{
			PACK T Values[2];
			PACK struct
			{
				PACK T X;
				PACK T Y;
			};
			PACK struct
			{
				PACK sf::Vector2<T> Sfml;
			};
		};
	};
	template<typename T>
	struct VecBase<3, T>
	{
	public:
		PACK union
		{
			PACK T Values[3];
			PACK struct
			{
				PACK T X;
				PACK T Y;
				PACK T Z;
			};
			PACK struct
			{
				PACK sf::Vector3<T> Sfml;
			};
		};
	};
	template<typename T>
	struct VecBase<4, T>
	{
	public:
		PACK union
		{
			PACK T Values[4];
			PACK struct
			{
				PACK T X;
				PACK T Y;
				PACK T Z;
				PACK T W;
			};
		};
	};
	
#if defined(SSE)
	template<>
	struct VecBase<4, float>
	{
	public:
		PACK union
		{
			PACK float Values[4];
			PACK struct
			{
				PACK float X;
				PACK float Y;
				PACK float Z;
				PACK float W;
			};
		};
#if defined(_MSC_VER) || defined(MAVC)
		__forceinline
#else
		inline 
#endif
			__m128 GetSimd() const
		{
			if (((size_t)this) & (size_t)0xf)
			{
				return _mm_setr_ps(this->X, this->Y, this->Z, this->W);
			}
			else
				return *((__m128*)(this));
		}
#if defined(_MSC_VER) || defined(MAVC)
		__forceinline
#else
		inline 
#endif
			void SetSimd(const __m128 Simd)
		{
			this->X = Simd.m128_f32[0];
			this->Y = Simd.m128_f32[1];
			this->Z = Simd.m128_f32[2];
			this->W = Simd.m128_f32[3];
		}
	};
	template<>
	struct VecBase<2, double>
	{
	public:
		PACK union
		{
			PACK double Values[2];
			PACK struct
			{
				PACK double X;
				PACK double Y;
			};
			PACK struct
			{
				PACK sf::Vector2<double> Sfml;
			};
		};
		
#if defined(_MSC_VER) || defined(MAVC)
		__forceinline
#else
		inline 
#endif
			__m128d GetSimd() const
		{
			if (((size_t)this) & (size_t)0xf)
			{
				return _mm_setr_pd(this->X, this->Y);
			}
			else
				return *((__m128d*)(this));
		}
#if defined(_MSC_VER) || defined(MAVC)
		__forceinline
#else
		inline 
#endif
			void SetSimd(const __m128d Simd)
		{
			this->X = Simd.m128d_f64[0];
			this->Y = Simd.m128d_f64[1];
		}
	};
#endif
#if !defined(AVX)
	template<>
	struct VecBase<8, float>
	{
	public:
		PACK union
		{
			PACK float Values[8];
			PACK struct
			{
				PACK float X;
				PACK float Y;
				PACK float Z;
				PACK float W;
				PACK float V;
				PACK float U;
				PACK float T;
				PACK float S;
			};
		};
#if defined(_MSC_VER) || defined(MAVC)
		__forceinline
#else
		inline 
#endif
			__m256 GetSimd() const
		{
			if (((size_t)this) & (size_t)0x1f)
			{
				return _mm256_setr_ps(this->X, this->Y, this->Z, this->W, this->V, this->U, this->T, this->S);
			}
			else
				return *((__m256*)(this));
		}
#if defined(_MSC_VER) || defined(MAVC)
		__forceinline
#else
		inline 
#endif
			void SetSimd(const __m256 Simd)
		{
			this->X = Simd.m256_f32[0];
			this->Y = Simd.m256_f32[1];
			this->Z = Simd.m256_f32[2];
			this->W = Simd.m256_f32[3];
			this->V = Simd.m256_f32[4];
			this->U = Simd.m256_f32[5];
			this->T = Simd.m256_f32[6];
			this->S = Simd.m256_f32[7];
		}
	};
	template<>
	struct VecBase<4, double>
	{
	public:
		PACK union
		{
			PACK double Values[4];
			PACK struct
			{
				PACK double X;
				PACK double Y;
				PACK double Z;
				PACK double W;
			};
		};
		
#if defined(_MSC_VER) || defined(MAVC)
		__forceinline
#else
		inline 
#endif
			__m256d GetSimd() const
		{
			if (((size_t)this) & (size_t)0x1f)
			{
				return _mm256_setr_pd(this->X, this->Y, this->Z, this->W);
			}
			else
				return *((__m256d*)(this));
		}
#if defined(_MSC_VER) || defined(MAVC)
		__forceinline
#else
		inline 
#endif
			void SetSimd(const __m256d Simd)
		{
			this->X = Simd.m256d_f64[0];
			this->Y = Simd.m256d_f64[1];
			this->Z = Simd.m256d_f64[2];
			this->W = Simd.m256d_f64[3];
		}
	};
#endif
}


template<unsigned int Dim, typename T>
struct Vec : public Private::VecBase<Dim, T>
{
	inline Vec() {}
	inline Vec(const T Value)
	{
		for(unsigned int i = 0; i < Dim; i++)
			this->Values[i] = Value;
	}
	inline Vec(const T X, const T Y)
	{
		this->Values[0] = X;
		this->Values[1] = Y;
	}
	inline Vec(const T X, const T Y, const T Z)
	{
		this->Values[0] = X;
		this->Values[1] = Y;
		this->Values[2] = Z;
	}
	inline Vec(const T X, const T Y, const T Z, const T W)
	{
		this->Values[0] = X;
		this->Values[1] = Y;
		this->Values[2] = Z;
		this->Values[3] = W;
	}
	inline Vec(const T X, const T Y, const T Z, const T W, const T V)
	{
		this->Values[0] = X;
		this->Values[1] = Y;
		this->Values[2] = Z;
		this->Values[3] = W;
		this->Values[4] = V;
	}
	inline Vec(const Vec<Dim, T>& Old)
	{
		for(unsigned int i = 0; i < Dim; i++)
			this->Values[i] = Old.Values[i];
	}
	template<unsigned int DimOld> static inline Vec<Dim, T> Redim(const Vec<DimOld, T> Old)
	{
		Vec<Dim, T> Return;
		for(unsigned int i = 0; i < min(Dim, DimOld); i++)
			Return.Values[i] = Old.Values[i];
		return Return;
	}
	template<unsigned int DimOld> static inline Vec<Dim, T> Redim(const Vec<DimOld, T> Old, const T Other)
	{
		Vec<Dim, T> Return;
		unsigned int i = 0;
		for(; i < min(Dim, DimOld); i++)
			Return.Values[i] = Old.Values[i];
		for (; i < Dim; i++)
			Return.Values[i] = Other;
		return Return;
	}

	T inline LengthSquare() const
	{
		T Return = (this->Values)[0] * (this->Values)[0];
		for(unsigned int i = 1; i < Dim; i++)
			Return += (this->Values)[i] * (this->Values)[i];
		return Return;
	}
	T inline Length() const
	{
		return Private::VecHelper<T>::sqrt(this->LengthSquare());
	}
	inline Vec<Dim, T>& Normalize()
	{
		return *this /= Length();
	}
	inline Vec<Dim, T> NormalizedCopy() const
	{
		return Vec<Dim, T>(*this).Normalize();
	}
	inline bool IsZero() const
	{
		const T Zero = static_cast<T>(0);
		for(unsigned int i = 0; i < Dim; i++)
			if((this->Values)[i] != Zero)
				return false;
		return true;
	}
	inline const T& operator [](const unsigned int Index) const
	{
		return (this->Values)[Index];
	}
	inline T& operator [](const unsigned int Index)
	{
		return (this->Values)[Index];
	}


	inline Vec<Dim, T> operator +(const Vec<Dim, T>& Other) const
	{
		Vec<Dim, T> Return;
		for(unsigned int i = 0; i < Dim; i++)
			Return.Values[i] = (this->Values)[i] + Other.Values[i];
		return Return;
	}
	inline Vec<Dim, T> operator +(const T Other) const
	{
		Vec<Dim, T> Return;
		for(unsigned int i = 0; i < Dim; i++)
			Return.Values[i] = (this->Values)[i] + Other;
		return Return;
	}
	inline Vec<Dim, T>& operator +=(const Vec<Dim, T>& Other)
	{
		for(unsigned int i = 0; i < Dim; i++)
			(this->Values)[i] += Other.Values[i];
		return *this;
	}
	inline Vec<Dim, T>& operator +=(const T Other)
	{
		for(unsigned int i = 0; i < Dim; i++)
			(this->Values)[i] += Other;
		return *this;
	}
	inline Vec<Dim, T> operator -(const Vec<Dim, T>& Other) const
	{
		Vec<Dim, T> Return;
		for(unsigned int i = 0; i < Dim; i++)
			Return.Values[i] = (this->Values)[i] - Other.Values[i];
		return Return;
	}
	inline Vec<Dim, T> operator -(const T Other) const
	{
		Vec<Dim, T> Return;
		for(unsigned int i = 0; i < Dim; i++)
			Return.Values[i] = (this->Values)[i] - Other;
		return Return;
	}
	inline Vec<Dim, T>& operator -=(const Vec<Dim, T>& Other)
	{
		for(unsigned int i = 0; i < Dim; i++)
			(this->Values)[i] -= Other.Values[i];
		return *this;
	}
	inline Vec<Dim, T>& operator -=(const T Other)
	{
		for(unsigned int i = 0; i < Dim; i++)
			(this->Values)[i] -= Other;
		return *this;
	}
	inline Vec<Dim, T> operator -() const
	{
		Vec<Dim, T> Return;
		for(unsigned int i = 0; i < Dim; i++)
			Return.Values[i] = -(this->Values)[i];
		return Return;
	}

	inline Vec<Dim, T> operator *(const Vec<Dim, T>& Other) const
	{
		Vec<Dim, T> Return;
		for(unsigned int i = 0; i < Dim; i++)
			Return.Values[i] = (this->Values)[i] * Other.Values[i];
		return Return;
	}

	inline Vec<Dim, T> operator *(const T Other) const
	{
		Vec<Dim, T> Return;
		for(unsigned int i = 0; i < Dim; i++)
			Return.Values[i] = (this->Values)[i] * Other;
		return Return;
	}
	inline Vec<Dim, T>& operator *= (const Vec<Dim, T>& Other)
	{
		for(unsigned int i = 0; i < Dim; i++)
			(this->Values)[i] *= Other.Values[i];
		return *this;
	}
	inline Vec<Dim, T>& operator *= (const T Other)
	{
		for(unsigned int i = 0; i < Dim; i++)
			(this->Values)[i] *= Other;
		return *this;
	}
	inline Vec<Dim, T> operator /(const Vec<Dim, T>& Other) const
	{
		Vec<Dim, T> Return;
		for(int i = 0; i < Dim; i++)
			Return.Values[i] = (this->Values)[i] / Other.Values[i];
		return Return;
	}
	inline Vec<Dim, T> operator /(const T Other) const
	{
		Vec<Dim, T> Return;
		for(unsigned int i = 0; i < Dim; i++)
			Return.Values[i] = (this->Values)[i] / Other;
		return Return;
	}
	inline Vec<Dim, T>& operator /=(const Vec<Dim, T>& Other)
	{
		for(unsigned int i = 0; i < Dim; i++)
			(this->Values)[i] /= Other.Values[i];
		return *this;
	}
	inline Vec<Dim, T>& operator /= (const T Other)
	{
		for(unsigned int i = 0; i < Dim; i++)
			(this->Values)[i] /= Other;
		return *this;
	}
	

	
	
	inline Vec<Dim, T> operator |(const Vec<Dim, T>& Other) const
	{
		Vec<Dim, T> Return;
		for(int i = 0; i < Dim; i++)
			Return.Values[i] = (this->Values)[i] | Other.Values[i];
		return Return;
	}
	inline Vec<Dim, T> operator |(const T Other) const
	{
		Vec<Dim, T> Return;
		for(unsigned int i = 0; i < Dim; i++)
			Return.Values[i] = (this->Values)[i] | Other;
		return Return;
	}
	inline Vec<Dim, T>& operator |=(const Vec<Dim, T>& Other)
	{
		for(unsigned int i = 0; i < Dim; i++)
			(this->Values)[i] |= Other.Values[i];
		return *this;
	}
	inline Vec<Dim, T>& operator |= (const T Other)
	{
		for(unsigned int i = 0; i < Dim; i++)
			(this->Values)[i] |= Other;
		return *this;
	}
	inline Vec<Dim, T> operator &(const Vec<Dim, T>& Other) const
	{
		Vec<Dim, T> Return;
		for(int i = 0; i < Dim; i++)
			Return.Values[i] = (this->Values)[i] & Other.Values[i];
		return Return;
	}
	inline Vec<Dim, T> operator &(const T Other) const
	{
		Vec<Dim, T> Return;
		for(unsigned int i = 0; i < Dim; i++)
			Return.Values[i] = (this->Values)[i] & Other;
		return Return;
	}
	inline Vec<Dim, T>& operator &=(const Vec<Dim, T>& Other)
	{
		for(unsigned int i = 0; i < Dim; i++)
			(this->Values)[i] &= Other.Values[i];
		return *this;
	}
	inline Vec<Dim, T>& operator &= (const T Other)
	{
		for(unsigned int i = 0; i < Dim; i++)
			(this->Values)[i] &= Other;
		return *this;
	}
	inline Vec<Dim, T> operator ^(const Vec<Dim, T>& Other) const
	{
		Vec<Dim, T> Return;
		for(int i = 0; i < Dim; i++)
			Return.Values[i] = (this->Values)[i] ^ Other.Values[i];
		return Return;
	}
	inline Vec<Dim, T> operator ^(const T Other) const
	{
		Vec<Dim, T> Return;
		for(unsigned int i = 0; i < Dim; i++)
			Return.Values[i] = (this->Values)[i] ^ Other;
		return Return;
	}
	inline Vec<Dim, T>& operator ^=(const Vec<Dim, T>& Other)
	{
		for(unsigned int i = 0; i < Dim; i++)
			(this->Values)[i] ^= Other.Values[i];
		return *this;
	}
	inline Vec<Dim, T>& operator ^= (const T Other)
	{
		for(unsigned int i = 0; i < Dim; i++)
			(this->Values)[i] ^= Other;
		return *this;
	}

	
	inline Vec<Dim, T> operator ||(const Vec<Dim, T>& Other) const
	{
		Vec<Dim, T> Return;
		for(int i = 0; i < Dim; i++)
			Return.Values[i] = (this->Values)[i] | Other.Values[i];
		return Return;
	}
	inline Vec<Dim, T> operator ||(const T Other) const
	{
		Vec<Dim, T> Return;
		for(unsigned int i = 0; i < Dim; i++)
			Return.Values[i] = (this->Values)[i] | Other;
		return Return;
	}
	inline Vec<Dim, T> operator &&(const Vec<Dim, T>& Other) const
	{
		Vec<Dim, T> Return;
		for(int i = 0; i < Dim; i++)
			Return.Values[i] = (this->Values)[i] & Other.Values[i];
		return Return;
	}
	inline Vec<Dim, T> operator &&(const T Other) const
	{
		Vec<Dim, T> Return;
		for(unsigned int i = 0; i < Dim; i++)
			Return.Values[i] = (this->Values)[i] & Other;
		return Return;
	}

	inline Vec<Dim, T>& operator = (const Vec<Dim, T>& Other)
	{
		for(unsigned int i = 0; i < Dim; i++)
			(this->Values)[i] = Other.Values[i];
		return *this;
	}
	inline bool operator == (const Vec<Dim, T>& Other) const
	{
		for(unsigned int i = 0; i < Dim; i++)
			if((this->Values[i]) != Other.Values[i])
				return false;
		return true;
	}
	inline bool operator != (const Vec<Dim, T>& Other) const
	{
		for(unsigned int i = 0; i < Dim; i++)
			if((this->Values[i]) != Other.Values[i])
				return true;
		return false;
	}
	// Konvertierung in anderes Vektorformat (gleiche Dimension)
	template<typename T2> inline operator Vec<Dim, T2>() const
	{
		Vec<Dim, T2> Return;
		for(unsigned int i = 0; i < Dim; i++)
			Return.Values[i] = static_cast<T2>((this->Values)[i]);
		return Return;
	}

	inline operator const T* () const
	{
		return this->Values;
	}
	inline operator T* ()
	{
		return this->Values;
	}

	
	inline T Dot(const Vec<Dim, T>& Other) const
	{
		T Return = (this->Values)[0] * Other.Values[0];
		for(unsigned int i = 1; i < Dim; i++)
			Return += (this->Values)[i] * Other.Values[i];
		return Return;
	}
	template<typename T2> inline Vec<3, T2> Cross(const Vec<3, T2>& Other)
	{
		return Vec<T2, 3>(this->Y * Other.Z - this->Z * Other.Y,
						 this->Z * Other.X - this->X * Other.Z,
						 this->X * Other.Y - this->Y * Other.X);
	}
	template<typename T2> inline Vec<4, T2> Cross(const Vec<4, T2>& Other)
	{
		return Vec<4, T2>(this->Y * Other.Z - this->Z * Other.Y + this->Z * Other.W -
						  this->W * Other.Z + this->Y * Other.W - this->W * Other.Y,
						  this->Z * Other.X - this->X * Other.Z + this->W * Other.X -
						  this->X * Other.W + this->Z * Other.W - this->W * Other.Z,
						  this->X * Other.Y - this->Y * Other.X + this->W * Other.Y -
						  this->Y * Other.W + this->W * Other.X - this->X * Other.W,
						  this->X * Other.Y - this->Y * Other.X + this->Y * Other.Z -
						  this->Z * Other.Y + this->X * Other.Z - this->Z * Other.X);
	}
};

/*#if defined(SSE2)
template<>
struct Vec<2, double> : public Private::VecBase<2, double>
{
	inline Vec() {}
#if defined(_MSC_VER) || defined(MAVC)
		__forceinline
#else
		inline 
#endif
	Vec(const __m128d Simd) 
	{
		this->SetSimd(Simd);
	}
	inline Vec(const double Value)
	{
		this->X = Value;
		this->Y = Value;
	}
	inline Vec(const double X, const double Y)
	{
		this->X = X;
		this->Y = Y;
	}
	inline Vec(const Vec<2, double>& Old)
	{
		this->X = Old.X;
		this->Y = Old.Y;
	}
	template<unsigned int DimOld> static inline Vec<2, double> Redim(const Vec<DimOld, double> Old)
	{
		Vec<2, double> Return;
		for(unsigned int i = 0; i < min(2, DimOld); i++)
			Return.Values[i] = Old.Values[i];
		return Return;
	}
	template<unsigned int DimOld> static inline Vec<2, double> Redim(const Vec<DimOld, double> Old, const double Other)
	{
		Vec<2, double> Return;
		unsigned int i = 0;
		for(; i < min(2, DimOld); i++)
			Return.Values[i] = Old.Values[i];
		for (; i < 2; i++)
			Return.Values[i] = Other;
		return Return;
	}

	double inline LengthSquare() const
	{
		const __m128d Simd = this->GetSimd();
		const __m128d Mul = _mm_mul_pd(Simd, Simd);
		return Mul.m128d_f64[0] + Mul.m128d_f64[1];
	}
	double inline Length() const
	{
		const __m128d Simd = this->GetSimd();
		const __m128d Mul = _mm_mul_pd(Simd, Simd);
#if SSE3
		const __m128d Zero = _mm_setzero_pd();
		return _mm_sqrt_sd(Zero, _mm_hadd_pd(Mul, Zero)).m128d_f64[0];
#else
		return sqrt(Mul.m128d_f64[0] + Mul.m128d_f64[1]);
#endif
	}
	inline Vec<2, double>& Normalize()
	{
		const __m128d Simd = this->GetSimd();
		this->SetSimd(_mm_div_pd(Simd, _mm_set1_pd(this->Length())));
	}
	inline Vec<2, double> NormalizedCopy() const
	{
		const __m128d Simd = this->GetSimd();
		return Vec<2, double>(_mm_div_pd(Simd, _mm_set1_pd(this->Length())));
	}
	inline bool IsZero() const
	{
		const double Zero = static_cast<double>(0);
		return (this->X != Zero) && (this->Y != Zero);
	}
	inline const double& operator [](const unsigned int Index) const
	{
		return (this->Values)[Index];
	}
	inline double& operator [](const unsigned int Index)
	{
		return (this->Values)[Index];
	}


	inline Vec<2, double> operator +(const Vec<2, double>& Other) const
	{
		return Vec<2, double>(_mm_add_pd(this->GetSimd(), Other.GetSimd()));
	}
	inline Vec<2, double> operator +(const double Other) const
	{
		return Vec<2, double>(_mm_add_pd(this->GetSimd(), _mm_set1_pd(Other)));
	}
	inline Vec<2, double>& operator +=(const Vec<2, double>& Other)
	{
		this->SetSimd(_mm_add_pd(this->GetSimd(), Other.GetSimd()));
		return *this;
	}
	inline Vec<2, double>& operator +=(const double Other)
	{
		this->SetSimd( _mm_add_pd(this->GetSimd(), _mm_set1_pd(Other)));
		return *this;
	}
	inline Vec<2, double> operator -(const Vec<2, double>& Other) const
	{
		return _mm_sub_pd(this->GetSimd(), Other.GetSimd());
	}
	inline Vec<2, double> operator -(const double Other) const
	{
		return _mm_sub_pd(this->GetSimd(), _mm_set1_pd(Other));
	}
	inline Vec<2, double>& operator -=(const Vec<2, double>& Other)
	{
		this->SetSimd(_mm_sub_pd(this->GetSimd(), Other.GetSimd()));
		return *this;
	}
	inline Vec<2, double>& operator -=(const double Other)
	{
		this->SetSimd(_mm_sub_pd(this->GetSimd(), _mm_set1_pd(Other)));
		return *this;
	}
	inline Vec<2, double> operator -() const
	{
		return Vec<2, double>(-(this->X), -(this->Y));
		//return Vec<2, double>(_mm_xor_pd(this->GetSimd(), __m128_SignMaskd));
	}

	inline Vec<2, double> operator *(const Vec<2, double>& Other) const
	{
		return Vec<2, double>(_mm_mul_pd(this->GetSimd(), Other.GetSimd()));
	}
	inline Vec<2, double> operator *(const double Other) const
	{
		return Vec<2, double>(_mm_mul_pd(this->GetSimd(), _mm_set1_pd(Other)));
	}
	inline Vec<2, double>& operator *= (const Vec<2, double>& Other)
	{
		this->SetSimd(_mm_mul_pd(this->GetSimd(), Other.GetSimd()));
		return *this;
	}
	inline Vec<2, double>& operator *= (const double Other)
	{
		this->SetSimd(_mm_mul_pd(this->GetSimd(), _mm_set1_pd(Other)));
		return *this;
	}
	inline Vec<2, double> operator /(const Vec<2, double>& Other) const
	{
		return Vec<2, double>(_mm_div_pd(this->GetSimd(), Other.GetSimd()));
	}
	inline Vec<2, double> operator /(const double Other) const
	{
		return Vec<2, double>(_mm_div_pd(this->GetSimd(), _mm_set1_pd(Other)));
	}
	inline Vec<2, double>& operator /=(const Vec<2, double>& Other)
	{
		this->SetSimd(_mm_div_pd(this->GetSimd(), Other.GetSimd()));
		return *this;
	}
	inline Vec<2, double>& operator /= (const double Other)
	{
		this->SetSimd(_mm_div_pd(this->GetSimd(), _mm_set1_pd(Other)));
		return *this;
	}
	

	
	
	

	inline Vec<2, double>& operator = (const Vec<2, double>& Other)
	{
		this->X = Other.X;
		this->Y = Other.Y;
		return *this;
	}
	inline bool operator == (const Vec<2, double>& Other) const
	{
		for(unsigned int i = 0; i < 2; i++)
			if((this->Values[i]) != Other.Values[i])
				return false;
		return true;
	}
	inline bool operator != (const Vec<2, double>& Other) const
	{
		for(unsigned int i = 0; i < 2; i++)
			if((this->Values[i]) != Other.Values[i])
				return true;
		return false;
	}
	// Konvertierung in anderes Vektorformat (gleiche Dimension)
	template<typename T2> inline operator Vec<2, T2>() const
	{
		Vec<2, T2> Return;
		for(unsigned int i = 0; i < 2; i++)
			Return.Values[i] = static_cast<T2>((this->Values)[i]);
		return Return;
	}

	inline operator const double* () const
	{
		return this->Values;
	}
	inline operator double* ()
	{
		return this->Values;
	}

	
	inline double Dot(const Vec<2, double>& Other) const
	{
		__m128d Mul = _mm_mul_pd(this->GetSimd(), Other.GetSimd());
		return Mul.m128d_f64[0] + Mul.m128d_f64[1];
	}
};
#endif*/

// Multipliktion mit Skalar von links
template<unsigned int Dim, typename T> inline Vec<Dim, T> operator * (const T This, const Vec<Dim, T>& Other)
{
	return Other * This;
}
template<unsigned int Dim, typename T> inline Vec<Dim, T> operator / (const T This, const Vec<Dim, T>& Other)
{
	Vec<2, double2> Return;
	for(unsigned int i = 0; i < Dim; i++)
		Return.Values[i] = This / (Other.Values)[i];
	return Return;
}
template<unsigned int Dim, typename T> inline Vec<Dim, T> operator - (const T This, const Vec<Dim, T>& Other)
{
	return Other - This;
}
template<unsigned int Dim, typename T> inline Vec<Dim, T> operator + (const T This, const Vec<Dim, T>& Other)
{
	return Other + This;
}

template<unsigned int Dim, typename T> inline Vec<Dim, T> operator ^ (const T This, const Vec<Dim, T>& Other)
{
	return Other ^ This;
}
template<unsigned int Dim, typename T> inline Vec<Dim, T> operator & (const T This, const Vec<Dim, T>& Other)
{
	return Other & This;
}
template<unsigned int Dim, typename T> inline Vec<Dim, T> operator | (const T This, const Vec<Dim, T>& Other)
{
	return Other | This;
}
template<unsigned int Dim, typename T> inline Vec<Dim, T> operator && (const T This, const Vec<Dim, T>& Other)
{
	return Other && This;
}
template<unsigned int Dim, typename T> inline Vec<Dim, T> operator || (const T This, const Vec<Dim, T>& Other)
{
	return Other || This;
}






#endif